Automation
BindAI Automation provides a foundation for defining executable automations, tracking individual runs, responding to events, and executing automation definitions synchronously or in the background. The current automation package provides:- Automation definitions
- Automation run lifecycle and execution state
- Automation run history
- Event triggers
- Trigger management and registry operations
- Synchronous automation execution
- Background execution using an in-process thread pool
- In-memory state and history implementations
Automation Architecture
The automation package separates automation definitions, execution state, historical records, event triggers, and background execution.AutomationWorker:
AutomationDefinitiondescribes an executable automation.AutomationRunrepresents one execution and its lifecycle state.AutomationStateStorestores the current state of a run.AutomationRunHistoryprovides an interface for recording and retrieving historical runs.EventTriggerconnects an event subscription to application-defined callable logic.AutomationWorkerexecutes automation definitions synchronously or in the background.
Automation Package
The automation package is provided bybindai-automation and imported as bindai_automation.
Automation Definitions
AutomationDefinition describes an automation and the executable target it invokes.
id— the automation definition identifier.name— a human-readable automation name.version— the definition version, starting at1.target— the executable target associated with the definition.metadata— optional application-defined metadata.
Automation Runs
AutomationRun represents one execution of an automation definition.
id— the unique execution identifier.definition_id— the automation definition identifier.definition_version— the definition version associated with the run.status— the execution state.input— input data stored on the run.output— execution output when available.error— failure information when execution fails.created_at— the run creation timestamp.started_at— the execution start timestamp.completed_at— the execution completion timestamp.
pending state. During execution, the worker moves a run to running, then to completed or failed, depending on the result.
Run timestamps are UTC-aware.
The run object represents execution state independently from the automation definition. Creating a run does not automatically execute the definition or persist the run in a store.
Automation State
AutomationStateStore defines the storage contract for the current state of automation runs.
A custom implementation can provide application-specific storage:
AutomationRun. This allows current run state to be managed independently of the run model and supports alternative storage implementations.
The state store represents the current execution state of a run. It does not, by itself, provide a permanent audit trail.
In-Memory State Store
MemoryAutomationStateStore provides an in-memory implementation of the automation state store.
MemoryAutomationStateStore is the default state store used by AutomationWorker when no custom state store is supplied.
Because it is in-memory, its state is process-local and is not durable across application restarts.
Applications requiring durable state can provide another AutomationStateStore implementation. The interface alone does not supply a database backend or guarantee persistence.
Automation Run History
AutomationRunHistory defines the history contract for recording and retrieving automation runs.
A custom implementation can provide application-specific history storage:
AutomationStateStore.
The state store answers:
What is the current execution state of this run?Run history answers:
Which recorded run can be retrieved from the history implementation?The history contract provides:
record(run)— record a run.get(run_id)— retrieve a recorded run by ID.list()— retrieve recorded runs.
In-Memory Run History
MemoryAutomationRunHistory provides an in-memory implementation of AutomationRunHistory.
MemoryAutomationRunHistory is the default history implementation used by AutomationWorker when no custom history implementation is supplied.
History records remain in memory and do not survive application restarts. A custom implementation is required for durable history.
Automation Worker
AutomationWorker executes automation definitions and manages the lifecycle of their AutomationRun objects.
Its current capabilities include:
- Synchronous execution
- Background execution
- Configurable state storage
- Configurable run history
- Configurable maximum worker count
- Worker shutdown
- Context-manager usage
- Creating an
AutomationRun. - Saving the initial run state.
- Starting the run.
- Executing the automation definition.
- Completing or failing the run.
- Saving the final run state.
- Recording the run in history.
input on the run, but the current execution path calls definition.run() without passing that input as an argument. Do not assume that the input is automatically delivered to the automation target.
The worker also does not provide automatic retries or durable background job delivery.
Worker Configuration
AutomationWorker accepts optional state and history implementations, along with a configurable thread-pool size.
MemoryAutomationStateStoreMemoryAutomationRunHistorymax_workers=4
ValueError indicating that max_workers must be at least 1.
Custom state and history implementations can be supplied when applications need different persistence behavior. Their durability, concurrency handling, and failure guarantees depend on the implementations themselves.
Synchronous Execution
The worker supports synchronous execution throughrun().
AutomationRun after execution completes or fails.
Conceptually:
definition.run().
Background Submission
The worker supports background execution throughsubmit().
submit() returns a Future whose result is an AutomationRun.
The future resolves when the submitted worker task finishes. The run records whether the automation completed or failed.
The worker uses an in-process thread pool for background execution. A future is not a persistent job record and does not guarantee that work will survive process termination.
Call shutdown() when the worker is no longer required.
Submit With Run
Applications that need a run object and identifier immediately can usesubmit_with_run().
submit_with_run() returns the AutomationRun and its Future immediately while execution proceeds in the background.
The worker saves the initial run state before submitting background execution. This allows an application to obtain the run identifier before execution has completed.
Conceptually:
Background Worker Model
In BindAI v0.1,AutomationWorker uses an in-process ThreadPoolExecutor.
Conceptually:
4.
Applications can configure it:
Worker Lifecycle
Workers should be shut down when they are no longer required:waitcontrols whether shutdown waits for running work to finish.cancel_futurescontrols whether pending futures are cancelled when supported by the underlying executor.
Context Manager
AutomationWorker can also be used as a context manager:
Run Execution
When the worker executes an automation, its lifecycle follows this general sequence:Automation Input
Automation runs accept an optionalinput value:
AutomationRun.
Current implementation note: The worker’s execution path calls definition.run() without passing the stored AutomationRun.input value as an argument.
Therefore, applications should not assume that the worker automatically injects input into the automation target. If execution logic needs that data, the application must arrange an explicit supported path for providing it.
Input propagation can be expanded in a future execution model.
Automation Output
A successful definition execution produces a result. The worker checks the result’s success state and uses the result output to complete the run. Conceptually:Automation Failures
If automation execution raises an exception, the worker catches it and marks the run as failed.status and error fields after execution.
The worker’s exception handling does not automatically retry failed runs. It also does not guarantee that every possible storage or process-level failure can be recovered from.
For critical workloads, consider persistence, idempotency, external side effects, and explicit failure-recovery behavior.
Worker and Event Triggers
AutomationWorker and EventTrigger solve different problems.
EventTrigger connects an event subscription to application logic:
AutomationWorker executes an AutomationDefinition:
Trigger
Trigger is the base abstraction for automation triggers.
Enabling and Disabling Triggers
Triggers expose methods for enabling and disabling their behavior:Event Triggers
EventTrigger connects a BindAI EventBus subscription to a target callable.
- An event bus
- An event name
- A target callable
BindAI Event System
BindAI’s execution context provides access to anEventBus through:
- Application lifecycle
- Agent execution
- Workflow execution
- Workflow nodes
- Human tasks
- Model requests and responses
- Tool execution
- Memory operations
- MCP connection lifecycle
EventTrigger can subscribe to a named event on an event bus and invoke its target when a matching event is delivered.
Do not assume that every category listed above is emitted in every execution path. Consult the event definitions and publishers for the runtime version being used.
Attaching an Event Trigger
AnEventTrigger must be attached before its subscription can receive matching events.
Detaching an Event Trigger
An attached trigger can be detached from its event source:detach() depends on the implementation’s lifecycle handling. For long-running applications, detach triggers when their subscriptions are no longer needed.
A typical lifecycle is:
Event Matching
EventTrigger subscribes to a specific event name.
For example:
Event-Driven Automation
A simple event-driven automation flow is:Targets
AnEventTrigger accepts a callable target.
Trigger State
Trigger attachment and enabled state are separate lifecycle concepts. Conceptually:Trigger Registry
TriggerRegistry provides a registry for trigger instances.
Registry Operations
TriggerRegistry provides operations for managing registered triggers.
Automation and Agents
Agents can participate in event-driven application behavior when their runtime operations publish events to a BindAI event bus. A conceptual flow is:Automation and Workflows
Automation can be combined with workflows through application-defined callable targets. A conceptual flow is:Automation and Connections
Automation can be combined with BindAI Connections through application code. For example:Automation and the REST API
BindAI’s REST API exposes background automation runs through these endpoints:AutomationWorker.
Conceptually:
202 Accepted and a run identifier. Clients can use the run identifier to request the run’s status and result information.
The API requires a valid API key when BINDAI_API_KEY is configured. If the server-side key is missing, the authentication dependency raises a configuration error rather than treating the request as an ordinary invalid-key request.
See Background Runs for the HTTP API details.
Automation State and the REST API
The REST API can expose the state of a background automation run. The response can include:- Run ID
- Automation definition ID
- Definition version
- Status
- Input
- Output
- Error
- Creation timestamp
- Start timestamp
- Completion timestamp
Background Runs and Process Lifetime
The current background worker is process-local. Conceptually:Horizontal Scaling
Running multiple API instances does not automatically create one shared background worker pool. For example:Persistent State and History
The default state and history implementations are in-memory:AutomationRun abstraction.
The default in-memory implementations are process-local and do not provide durable persistence across application restarts. Persistent behavior, consistency guarantees, and concurrent-access behavior depend on the custom implementations supplied by the application.
Error Handling
The underlying BindAIEventBus and the automation worker have different error-handling responsibilities.
The current event system handles exceptions raised by event handlers according to its event-dispatch implementation. Applications should consult that implementation when relying on handler isolation, logging, or continued delivery to other handlers.
EventTrigger does not provide a separate universal retry or failure-recovery system.
For background automation execution, AutomationWorker catches exceptions raised during definition execution and records the resulting failure on the AutomationRun.
Applications requiring additional retries, persistence, dead-letter handling, or failure recovery must implement those concerns at the appropriate automation, workflow, or infrastructure layer.
Synchronous Event Processing
The current coreEventBus processes event handlers synchronously.
Conceptually:
EventTrigger does not automatically create a background worker or persistent job.
If event handling requires explicit background execution, the application can invoke an AutomationWorker or another execution mechanism from the target. For example, a target can submit an automation definition to a worker when that is appropriate for the application’s design.
This keeps event delivery and background execution as separate responsibilities.
Because event processing is synchronous, a slow target can affect the time taken by the event-dispatch operation.
Trigger Lifecycle
A typical trigger lifecycle is:Testing Automation
Automation components should be tested independently from external services they may eventually control. Useful tests include:- Trigger construction
- Enable/disable behavior
- Attach behavior
- Detach behavior
- Event matching
- Target invocation
- Duplicate-attachment handling, where implemented
- Registry operations
- Handler failure behavior
- Automation run lifecycle
- State-store operations
- Run-history recording
- Run-history retrieval
- Run-history snapshot isolation
- Synchronous worker execution
- Background worker execution
- Background worker state updates
- Background worker run-history recording
- Worker shutdown behavior
- Worker configuration validation
input to the worker stores it on the run but does not automatically pass it to definition.run() in the current implementation.
For tests involving asynchronous execution, wait for the returned future before asserting the final run state or history.
Security Considerations
Automation can cause actions to occur automatically in response to events. Applications should consider:- Which events are allowed to trigger automation
- Which targets can be invoked
- Whether a target performs external side effects
- Credential and secret handling
- Authorization boundaries
- Input validation
- Audit requirements
- Duplicate event handling and idempotency
- Failure behavior when external services are unavailable
Production Considerations
The in-process worker model is a lightweight execution mechanism, not a guarantee of durable job processing. Production deployments should consider:- Application and container restarts
- Long-running automation
- Worker capacity
- External-service failures
- Retry behavior
- Idempotency
- Monitoring and observability
- Run-state persistence
- Failure recovery
- Shutdown behavior
- Cross-instance coordination
Current Scope
The current BindAI Automation package provides the following capabilities.Automation
AutomationDefinitionAutomationRunAutomationStateStoreMemoryAutomationStateStoreAutomationRunHistoryMemoryAutomationRunHistoryAutomationWorker
Worker execution
- Synchronous execution
- Background execution
submit_with_run()- Configurable thread-pool size
- Worker shutdown
- Context-manager support
- Run-state updates
- Run-history recording
Event integration
TriggerEventTrigger- BindAI
EventBusintegration - Named event subscriptions
- Event-driven callable targets
- Enable/disable lifecycle
- Attach/detach lifecycle
Registry support
TriggerRegistry- Trigger registration
- Trigger lookup
- Trigger removal
- Trigger enumeration
- Registry clearing
REST API integration
The BindAI API also provides:- Background run submission
- Run identifiers
- Run status lookup
- Run output
- Run error information
Current Limitations
The current v0.1 automation implementation does not provide the following as built-in capabilities:- Distributed job queues
- Durable distributed workers
- Cross-process worker coordination
- Automatic worker failover
- Built-in worker autoscaling
- Database-backed state by default
- Database-backed history by default
- Kubernetes-native job execution
- A hosted automation dashboard
- Advanced event-routing infrastructure
- Automatic delivery of
AutomationRun.inputtoAutomationDefinition.run() - Automatic retries for failed background automation runs
- Guaranteed completion of in-process jobs after application termination
Future Automation Capabilities
Future automation development could include:- Advanced event routing
- Additional trigger types
- Persistent database-backed automation state
- Persistent database-backed run history
- Distributed queue-based execution
- Coordinated worker processes
- More advanced scheduling and execution policies
- Broader automation orchestration
- Monitoring and operational tooling
- Improved automation input and context propagation
- More comprehensive retry and recovery policies
Design Principles
BindAI Automation follows several design principles:- Keep triggers small and composable.
- Reuse the existing event system.
- Separate event detection from automation actions.
- Make trigger lifecycle explicit.
- Keep background execution explicit.
- Keep external-service concerns outside the trigger abstraction.
- Allow additional trigger types without unnecessarily changing the core event infrastructure.
- Keep automation state separate from event subscriptions.
- Keep current execution state separate from historical run records.
- Keep the history interface small so alternative backends can be introduced.
- Use
AutomationWorkerfor explicit synchronous and background execution. - Avoid implying distributed execution where only process-local execution exists.
- Document automation input behavior according to the actual execution path.
- Make durability and failure-recovery guarantees dependent on the configured infrastructure.
API Accuracy
This guide describes the APIs implemented by the currentbindai-automation package and its integration with BindAI’s event system.
The public automation API used here includes:
AutomationWorker provides:
ThreadPoolExecutor.
The default state store is MemoryAutomationStateStore.
The default run-history implementation is MemoryAutomationRunHistory.
The current automation layer does not claim to provide higher-level APIs such as:
AutomationRunHistory contract and its in-memory implementation, MemoryAutomationRunHistory. Persistent database-backed history is not supplied by the default implementation.
Background execution is available through AutomationWorker, but it is process-local rather than distributed.
One important implementation detail is that AutomationWorker stores submitted input on AutomationRun, but its current execution path calls:
Summary
BindAI Automation provides a lightweight foundation for stateful and event-driven automation. The current architecture separates automation definitions, execution state, historical records, triggers, and background execution:EventTrigger connects BindAI’s existing EventBus system to application-defined callable targets.
AutomationRun represents an individual execution. AutomationStateStore manages current run state, while AutomationRunHistory provides a separate interface for historical records.
AutomationWorker provides synchronous and background execution using an in-process thread pool. Its default state and history implementations are in-memory, and submitted input is stored on the run but is not automatically passed to AutomationDefinition.run().
The REST API can submit and inspect background automation runs through:
